package com.css.fxfzysx.modules.vaolEngineering.utils;

import java.util.HashMap;

/**
 * 最小二乘法
 */
public class LeastSquaresRegression {

    Integer[] xData;
    Double[] yData;

    public static HashMap<Integer,Double> leastSquareMethod(Integer[] xData, Double[] yData, Integer[] preX) {
        return new LeastSquaresRegression(xData, yData).predict(preX);
    }

//    public static void main(String[] args) {
//        int[] xData = new int[]{6,7,8,9,10};
//        double[] yData = new double[]{0.08,0.21,0.5,0.77,1};
//        int[] preX = {6,7,8,9,10,11};
//        HashMap<Integer, Double> map = leastSquareMethod(xData, yData, preX);
//        map.forEach((k,v)->{
//            System.out.println("当x轴为"+k+"时，预测y轴为+"+v);
//        });
//    }

    public HashMap<Integer,Double> predict(Integer[] preX) {

        // 计算n
        int n = xData.length;
        // 计算x，y，xy，x²的总和
        double totalX = 0d;
        double totalY = 0d;
        double totalXY = 0d;
        double totalX2 = 0d;
        for (int i = 0; i < xData.length; i++) {
            totalX += xData[i];
            totalY += yData[i];
            totalXY += xData[i] * yData[i];
            totalX2 += xData[i] * xData[i];
        }
        // 计算x和y的均值
        double meanX = totalX / n;
        double meanY = totalY / n;
        // 计算斜率b
        double b = (totalXY - n * meanX * meanY) / (totalX2 - n * meanX * meanX);
        // 计算截距a
        double a = meanY - b * meanX;
        // 预测
        HashMap<Integer, Double> map = new HashMap<>();
        for (int x : preX) {
            Double result = Double.valueOf(String.format("%.2f", a + b * x));
            map.put(x,result);
        }
        return map;
    }

    public LeastSquaresRegression(Integer[] xData, Double[] yData) {
        this.xData = xData;
        this.yData = yData;
    }
}
